#include "com_voe_VoEFile.h"
#include "jni_api.h"
#include "OutputParam.h"
#include "voe_file.h"
#include "InStreamImpl.h"
#include "OutStreamImpl.h"

extern webrtc::CodecInst* convert(JNIEnv* env, jobject obj, webrtc::CodecInst* codecInst);

/*
 * Class:     com_voe_VoEFile
 * Method:    GetInterface
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_com_voe_VoEFile_GetInterface
  (JNIEnv * env, jclass cls, jlong p_voiceEngine)
{
	return (jlong)webrtc::VoEFile::GetInterface((webrtc::VoiceEngine*)p_voiceEngine);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    Release
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_Release
  (JNIEnv * env, jclass cls, jlong p)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->Release();
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StartPlayingFileLocally
 * Signature: (JILjava/lang/String;ZIFII)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StartPlayingFileLocally
  (JNIEnv * env, jclass cls, jlong p, jint channel, jstring fileNameUTF8, jboolean loop,
  jint format, jfloat volumeScaling, jint startPointMs, jint stopPointMs)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->StartPlayingFileLocally(channel, 
		JniHelper::j2c_string(env, fileNameUTF8).c_str(), loop != 0, 
		(webrtc::FileFormats)format, volumeScaling, startPointMs, stopPointMs);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StartPlayingFileLocally2
 * Signature: (JILcom/voe/callback/InStream;IFII)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StartPlayingFileLocally2
  (JNIEnv * env, jclass cls, jlong p, jint channel, jobject instream, jint format, 
  jfloat volumeScaling, jint startPointMs, jint stopPointMs)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	InStreamImpl* _InStream = new InStreamImpl();
	if(_InStream->set(env, instream))
	{
		return pVoeFile->StartPlayingFileLocally(channel, _InStream, 
			(webrtc::FileFormats)format, volumeScaling, startPointMs, stopPointMs);
	}
	else
	{
		delete _InStream;
		return JCB_Err_Set;
	}
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StopPlayingFileLocally
 * Signature: (JI)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StopPlayingFileLocally
  (JNIEnv * env, jclass cls, jlong p, jint channel)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->StopPlayingFileLocally(channel);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    IsPlayingFileLocally
 * Signature: (JI)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_IsPlayingFileLocally
  (JNIEnv * env, jclass cls, jlong p, jint channel)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->IsPlayingFileLocally(channel);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ScaleLocalFilePlayout
 * Signature: (JIF)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ScaleLocalFilePlayout
	(JNIEnv * env, jclass cls, jlong p, jint channel, jfloat scale)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->ScaleLocalFilePlayout(channel, scale);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StartPlayingFileAsMicrophone
 * Signature: (JILjava/lang/String;ZZIF)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StartPlayingFileAsMicrophone
  (JNIEnv * env, jclass cls, jlong p, jint channel, jstring fileNameUTF8, jboolean loop,
  jboolean mixWithMicrophone, jint format, jfloat volumeScaling)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->StartPlayingFileAsMicrophone(channel, 
		JniHelper::j2c_string(env, fileNameUTF8).c_str(), loop != 0 , mixWithMicrophone != 0, 
		(webrtc::FileFormats)format, volumeScaling);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StartPlayingFileAsMicrophone2
 * Signature: (JILcom/voe/callback/InStream;ZIF)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StartPlayingFileAsMicrophone2
  (JNIEnv * env, jclass cls, jlong p, jint channel, jobject instream, jboolean mixWithMicrophone,
  jint format, jfloat volumeScaling)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	InStreamImpl* _InStream = new InStreamImpl;
	if(_InStream->set(env, instream))
	{
		return pVoeFile->StartPlayingFileAsMicrophone(channel, _InStream, mixWithMicrophone != 0, 
			(webrtc::FileFormats)format, volumeScaling);
	}
	else
	{
		delete _InStream;
		return JCB_Err_Set;
	}
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StopPlayingFileAsMicrophone
 * Signature: (JI)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StopPlayingFileAsMicrophone
  (JNIEnv * env, jclass cls, jlong p, jint channel)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->StopPlayingFileAsMicrophone(channel);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    IsPlayingFileAsMicrophone
 * Signature: (JI)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_IsPlayingFileAsMicrophone
	(JNIEnv * env, jclass cls, jlong p, jint channel)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->IsPlayingFileAsMicrophone(channel);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ScaleFileAsMicrophonePlayout
 * Signature: (JIF)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ScaleFileAsMicrophonePlayout
	(JNIEnv * env, jclass cls, jlong p, jint channel, jfloat scale)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->ScaleFileAsMicrophonePlayout(channel, scale);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StartRecordingPlayout
 * Signature: (JILjava/lang/String;Lcom/voe/common/CodecInst;I)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StartRecordingPlayout
	(JNIEnv * env, jclass cls, jlong p, jint channel, jstring fileNameUTF8, jobject obj, jint maxSizeBytes)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	webrtc::CodecInst codecInst = {0};
	return pVoeFile->StartRecordingPlayout(channel,
		JniHelper::j2c_string(env, fileNameUTF8).c_str(),
		convert(env, obj, &codecInst),
		maxSizeBytes);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StopRecordingPlayout
 * Signature: (JI)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StopRecordingPlayout
  (JNIEnv * env, jclass cls, jlong p, jint channel)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->StopRecordingPlayout(channel);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StartRecordingPlayout2
 * Signature: (JILcom/voe/callback/OutStream;Lcom/voe/common/CodecInst;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StartRecordingPlayout2
	(JNIEnv * env, jclass cls, jlong p, jint channel, jobject outstream, jobject obj)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	webrtc::CodecInst codecInst = {0};
	OutStreamImpl* _OutStream = new OutStreamImpl;
	if(_OutStream->set(env, outstream))
	{
		return pVoeFile->StartRecordingPlayout(channel, _OutStream, convert(env, obj, &codecInst));
	}
	else
	{
		delete _OutStream;
		return JCB_Err_Set;
	}
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StartRecordingMicrophone
 * Signature: (JLjava/lang/String;Lcom/voe/common/CodecInst;I)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StartRecordingMicrophone
  (JNIEnv * env, jclass cls, jlong p, jstring fileNameUTF8, jobject obj, jint maxSizeBytes)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	webrtc::CodecInst codecInst = {0};
	return pVoeFile->StartRecordingMicrophone(
		JniHelper::j2c_string(env, fileNameUTF8).c_str(),
		convert(env, obj, &codecInst), maxSizeBytes);
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StartRecordingMicrophone2
 * Signature: (JLcom/voe/callback/OutStream;Lcom/voe/common/CodecInst;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StartRecordingMicrophone2
  (JNIEnv * env, jclass cls, jlong p, jobject outstream, jobject obj)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	webrtc::CodecInst codecInst = {0};
	OutStreamImpl* _OutStream = new OutStreamImpl;
	if(_OutStream->set(env, outstream))
	{
		return pVoeFile->StartRecordingMicrophone(_OutStream, convert(env, obj, &codecInst));
	}
	else
	{
		delete _OutStream;
		return JCB_Err_Set;
	}
}

/*
 * Class:     com_voe_VoEFile
 * Method:    StopRecordingMicrophone
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_StopRecordingMicrophone
  (JNIEnv * env, jclass cls, jlong p)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->StopRecordingMicrophone();
}

/*
 * Class:     com_voe_VoEFile
 * Method:    GetFileDuration
 * Signature: (JLjava/lang/String;Lcom/voe/common/OutputParam;I)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_GetFileDuration
  (JNIEnv * env, jclass cls, jlong p, jstring fileNameUTF8, jobject obj, jint format)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	int durationMs = 0;
	jint result = pVoeFile->GetFileDuration(JniHelper::j2c_string(env, fileNameUTF8).c_str(),
		durationMs, (webrtc::FileFormats)format);
	if(result == 0)
	{
		JniOutputBuilder job(env);
		OutputParam param(env, obj);
		param.setArray(job.add(durationMs).getOutput());
	}
	return result;
}

/*
 * Class:     com_voe_VoEFile
 * Method:    GetPlaybackPosition
 * Signature: (JILcom/voe/common/OutputParam;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_GetPlaybackPosition
  (JNIEnv * env, jclass cls, jlong p, jint channel, jobject obj)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	int positionMs = 0;
	jint result = pVoeFile->GetPlaybackPosition(channel, positionMs);
	if(result == 0)
	{
		JniOutputBuilder job(env);
		OutputParam param(env, obj);
		param.setArray(job.add(positionMs).getOutput());
	}
	return result;
}
//virtual int ConvertPCMToWAV(InStream* streamIn, OutStream* streamOut) = 0
/*
 * Class:     com_voe_VoEFile
 * Method:    ConvertPCMToWAV
 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ConvertPCMToWAV
	(JNIEnv * env, jclass cls, jlong p, jstring fileNameInUTF8, jstring fileNameOutUTF8)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->ConvertPCMToWAV(JniHelper::j2c_string(env, fileNameInUTF8).c_str(), 
		JniHelper::j2c_string(env, fileNameOutUTF8).c_str());
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ConvertPCMToWAV2
 * Signature: (JLcom/voe/callback/InStream;Lcom/voe/callback/OutStream;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ConvertPCMToWAV2
  (JNIEnv * env, jclass cls, jlong p, jobject streamIn, jobject streamOut)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	InStreamImpl* _InStream = new InStreamImpl;
	OutStreamImpl* _OutStream = new OutStreamImpl;
	if(_InStream->set(env, streamIn) && _OutStream->set(env, streamOut))
	{
		return pVoeFile->ConvertPCMToWAV(_InStream, _OutStream);
	}
	else
	{
		delete _InStream;
		delete _OutStream;
		return JCB_Err_Set;
	}
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ConvertWAVToPCM
 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ConvertWAVToPCM
	(JNIEnv * env, jclass cls, jlong p, jstring fileNameInUTF8, jstring fileNameOutUTF8)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->ConvertPCMToWAV(JniHelper::j2c_string(env, fileNameInUTF8).c_str(), 
		JniHelper::j2c_string(env, fileNameOutUTF8).c_str());
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ConvertWAVToPCM2
 * Signature: (JLcom/voe/callback/InStream;Lcom/voe/callback/OutStream;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ConvertWAVToPCM2
	(JNIEnv * env, jclass cls, jlong p, jobject streamIn, jobject streamOut)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	InStreamImpl* _InStream = new InStreamImpl;
	OutStreamImpl* _OutStream = new OutStreamImpl;
	if(_InStream->set(env, streamIn) && _OutStream->set(env, streamOut))
	{
		return pVoeFile->ConvertWAVToPCM(_InStream, _OutStream);
	}
	else
	{
		delete _InStream;
		delete _OutStream;
		return JCB_Err_Set;
	}
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ConvertPCMToCompressed
 * Signature: (JLjava/lang/String;Ljava/lang/String;Lcom/voe/common/CodecInst;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ConvertPCMToCompressed
  (JNIEnv * env, jclass cls, jlong p, jstring fileNameInUTF8, jstring fileNameOutUTF8, jobject obj)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	webrtc::CodecInst codecInst = {0};
	return pVoeFile->ConvertPCMToCompressed(JniHelper::j2c_string(env, fileNameInUTF8).c_str(), 
		JniHelper::j2c_string(env, fileNameOutUTF8).c_str(), convert(env, obj, &codecInst));
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ConvertPCMToCompressed2
 * Signature: (JLcom/voe/callback/InStream;Lcom/voe/callback/OutStream;Lcom/voe/common/CodecInst;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ConvertPCMToCompressed2
	(JNIEnv * env, jclass cls, jlong p, jobject streamIn, jobject streamOut, jobject obj)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	webrtc::CodecInst codecInst = {0};
	InStreamImpl* _InStream = new InStreamImpl;
	OutStreamImpl* _OutStream = new OutStreamImpl;
	if(_InStream->set(env, streamIn) && _OutStream->set(env, streamOut))
	{
		return pVoeFile->ConvertPCMToCompressed(_InStream, _OutStream, convert(env, obj, &codecInst));
	}
	else
	{
		delete _InStream;
		delete _OutStream;
		return JCB_Err_Set;
	}
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ConvertCompressedToPCM
 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ConvertCompressedToPCM
	(JNIEnv * env, jclass cls, jlong p, jstring fileNameInUTF8, jstring fileNameOutUTF8)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	return pVoeFile->ConvertCompressedToPCM(JniHelper::j2c_string(env, fileNameInUTF8).c_str(), 
		JniHelper::j2c_string(env, fileNameOutUTF8).c_str());
}

/*
 * Class:     com_voe_VoEFile
 * Method:    ConvertCompressedToPCM2
 * Signature: (JLcom/voe/callback/InStream;Lcom/voe/callback/OutStream;)I
 */
JNIEXPORT jint JNICALL Java_com_voe_VoEFile_ConvertCompressedToPCM2
	(JNIEnv * env, jclass cls, jlong p, jobject streamIn, jobject streamOut)
{
	webrtc::VoEFile* pVoeFile = (webrtc::VoEFile*)p;
	InStreamImpl* _InStream = new InStreamImpl;
	OutStreamImpl* _OutStream = new OutStreamImpl;
	if(_InStream->set(env, streamIn) && _OutStream->set(env, streamOut))
	{
		return pVoeFile->ConvertCompressedToPCM(_InStream, _OutStream);
	}	
	else
	{
		delete _InStream;
		delete _OutStream;
		return JCB_Err_Set;
	}
}